package data

import (
	"context"
	"time"

	"github.com/go-kratos/kratos/v2/log"

	"gitee.com/danqingzhao/go-dango/apps/user/biz"
	"gitee.com/danqingzhao/go-dango/apps/user/conf"
	"gitee.com/danqingzhao/go-dango/pkg/proto/auth"
	"gitee.com/danqingzhao/go-dango/pkg/proto/settings"
	"gitee.com/danqingzhao/go-dango/pkg/third/orm"
)

type buttonRepo struct {
	data *Data
	log  *log.Helper
}

func NewButtonRepo(data *Data, logHelpers *settings.LogHelpers) biz.ButtonRepo {
	return &buttonRepo{data: data, log: logHelpers.Data}
}

func (r *buttonRepo) CreateModel(ctx context.Context, m *biz.ButtonModel) error {
	now := time.Now()
	m.CreatedAt = now
	m.UpdatedAt = now
	if err := orm.DBCreate(ctx, r.data.gormDB, &biz.ButtonModel{}, m); err != nil {
		r.log.WithContext(ctx).Error(err.Error())
		return err
	}
	return nil
}

func (r *buttonRepo) UpdateModel(ctx context.Context, m biz.ButtonModel, upmap map[string]any, conds ...any) error {
	m.UpdatedAt = time.Now()
	if err := orm.DBUpdate(ctx, r.data.gormDB, &m, &biz.ButtonModel{}, upmap, conds...); err != nil {
		r.log.WithContext(ctx).Error(err.Error())
		return err
	}
	return nil
}

func (r *buttonRepo) DeleteModel(ctx context.Context, conds ...any) error {
	if err := orm.DBDelete(ctx, r.data.gormDB, &biz.ButtonModel{}, conds...); err != nil {
		r.log.WithContext(ctx).Error(err.Error())
		return err
	}
	return nil
}

func (r *buttonRepo) FindModel(
	ctx context.Context,
	preloads []string,
	conds ...any,
) (*biz.ButtonModel, error) {
	var m biz.ButtonModel
	if err := orm.DBFind(ctx, r.data.gormDB, preloads, &m, conds...); err != nil {
		r.log.WithContext(ctx).Error(err.Error())
		return nil, err
	}
	return &m, nil
}

func (r *buttonRepo) ListModel(
	ctx context.Context,
	qp orm.QueryParams,
) (int64, []biz.ButtonModel, error) {
	var ms []biz.ButtonModel
	count, err := orm.DBList(ctx, r.data.gormDB, &biz.ButtonModel{}, &ms, qp)
	if err != nil {
		r.log.WithContext(ctx).Error(err.Error())
		return 0, nil, err
	}
	return count, ms, nil
}

func (r *buttonRepo) ListPolicies(ctx context.Context, m biz.ButtonModel) ([][]string, [][]string) {
	sub := auth.PolicyButtonSub(conf.APPName, m.Id)
	rules := make([][]string, len(m.Permissions))
	for i, rp := range m.Permissions {
		rules[i] = []string{sub, rp.GrpcUrl, "GRPC"}
	}
	return rules, [][]string{{sub, auth.PolicyMenuSub(conf.APPName, m.MenuId)}}
}
